home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / misc / gms_sound.lha / Sound / sound.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-07  |  10.1 KB  |  298 lines

  1. /*
  2. ** Module:    Sound.
  3. ** Author:    Paul Manias
  4. ** Copyright: DreamWorld Productions (c) 1996-1998.  All rights reserved.
  5. **
  6. ** --------------------------------------------------------------------------
  7. ** 
  8. ** TERMS AND CONDITIONS
  9. ** 
  10. ** This source code is made available on the condition that it is only used to
  11. ** further enhance the Games Master System.  IT IS NOT DISTRIBUTED FOR THE USE
  12. ** IN OTHER PRODUCTS.  Developers may edit and re-release this source code
  13. ** only in the form of its GMS module.  Use of this code outside of the module
  14. ** is not permitted under any circumstances.
  15. ** 
  16. ** This source code stays the copyright of DreamWorld Productions regardless
  17. ** of what changes or additions are made to it by 3rd parties.  A joint
  18. ** copyright can be granted if the 3rd party wishes to retain some ownership
  19. ** of said modifications.
  20. ** 
  21. ** In exchange for our distribution of this source code, we also ask you to
  22. ** distribute the source when releasing a modified version of this module.
  23. ** This is not compulsory if any additions are sensitive to 3rd party
  24. ** copyrights, or if it would damage any commercial product(s).
  25. ** 
  26. ** --------------------------------------------------------------------------
  27. **
  28. ** BUGS AND MISSING FEATURES
  29. ** -------------------------
  30. ** If you correct a bug or fill in a missing feature, the source should be
  31. ** e-mailed to pmanias@ihug.co.nz for inclusion in the next update of this
  32. ** module.
  33. **
  34. ** + Support for Sound->Frequency.
  35. **
  36. ** + WAVE Support - to be implemented as a child module (ie not in this
  37. **   source code).
  38. **
  39. ** CHANGES
  40. ** -------
  41. ** -1997-
  42. ** 27 Oct Replaced IFF body search with better one from Screens module.
  43. **        Added support for CheckFile().
  44. ** 30 Oct Optimised the way audio channels are allocated from the OS.
  45. **        Sound now supports Deactivate().
  46. **        Edited too many parts to note!  Document the flags.
  47. ** 31 Oct Implemented SLEFT, SRIGHT, SFORCE.
  48. **
  49. ** -1998-
  50. ** 29 Jan Added a Pair field for modulation.
  51. ** 14 Mar Removed the Sound->Header field.
  52. ** 18 Jul Moved precalculated arrays from asm to C.
  53. **        Removed data=faronly from the SCOPTIONS file.
  54. **        Added support for field orientation.
  55. */
  56.  
  57. #include <proto/dpkernel.h>
  58. #include <system/all.h>
  59. #include <dpkernel/prefs.h>
  60. #include "defs.h"
  61.  
  62. /***********************************************************************************/
  63.  
  64. BYTE ModAuthor[]    = "Paul Manias";
  65. BYTE ModDate[]      = "July 1998";
  66. BYTE ModCopyright[] = "DreamWorld Productions (c) 1996-1998.  All rights reserved.";
  67. BYTE ModName[]      = "Sound";
  68.  
  69. /***********************************************************************************/
  70.  
  71. struct Function JumpTableV1[] = {
  72.   { LIBAllocSoundMem, "AllocSoundMem(d0l,d1l)" },
  73.   { LIBStopAudio,     "StopAudio()"            },
  74.   { LIBCheckSound,    "CheckSound(a0l)"        },
  75.   { LIBFreeSoundMem,  "FreeSoundMem(d0l)"      },
  76.   { LIBSetVolume,     "SetVolume(a0l,d0w)"     },
  77.   { NULL, NULL }
  78. };
  79.  
  80. /***********************************************************************************/
  81.  
  82. struct FieldDef AttribFlags[] = {
  83.   { "BIT16",  0x00000001 }, { "MODVOL", 0x00000002 }, { "MODPER",   0x00000004 },
  84.   { "REPEAT", 0x00000008 }, { "EMPTY",  0x00000010 }, { "LEFT",     0x00000020 },
  85.   { "RIGHT",  0x00000040 }, { "FORCE",  0x00000080 }, { "STOPLAST", 0x00000100 },
  86.   { NULL, NULL }
  87. };
  88.  
  89. struct FieldDef SndOctave[] = {
  90.   { "G0",   2  }, { "F0S",  4  }, { "F0",   6  }, { "E0",   8  },
  91.   { "D0S", 10  }, { "D0",  12  }, { "C0S", 14  }, { "C0",  16  },
  92.   { "B0",  18  }, { "A0S", 20  }, { "A0",  22  }, { "G1S", 24  },
  93.   { "G1",  26  }, { "F1S", 28  }, { "F1",  30  }, { "E1",  32  },
  94.   { "D1S", 34  }, { "D1",  36  }, { "C1S", 38  }, { "C1",  40  },
  95.   { "B1",  42  }, { "A1S", 44  }, { "A1",  46  }, { "G2S", 48  },
  96.   { "G2",  50  }, { "F2S", 52  }, { "F2",  54  }, { "E2",  56  },
  97.   { "D2S", 58  }, { "D2",  60  }, { "C2S", 62  }, { "C2",  64  },
  98.   { "B2",  66  }, { "A2S", 68  }, { "A2",  70  }, { "G3S", 72  },
  99.   { "G3",  74  }, { "F3S", 76  }, { "F3",  78  }, { "E3",  80  },
  100.   { "D3S", 82  }, { "D3",  84  }, { "C3S", 86  }, { "C3",  88  },
  101.   { "B3",  90  }, { "A3S", 92  }, { "A3",  94  }, { "G4S", 96  },
  102.   { "G4",  98  }, { "F4S", 100 }, { "F4",  102 }, { "E4",  104 },
  103.   { "D4S", 106 }, { "D4",  108 }, { "C4S", 110 }, { "C4",  112 },
  104.   { "B4",  114 }, { "A4S", 116 }, { "A4",  118 }, { "G5S", 120 },
  105.   { "G5",  122 }, { "F5S", 124 }, { "F5",  126 }, { "E5",  128 },
  106.   { "D5S", 130 }, { "D5",  132 }, { "C5S", 134 }, { "C5",  136 },
  107.   { "B5",  138 }, { "A5S", 140 }, { "A5",  142 }, { "G6S", 144 },
  108.   { "G6",  146 }, { "F6S", 148 }, { "F6",  150 }, { "E6",  152 },
  109.   { "D6S", 154 }, { "D6",  156 }, { "C6S", 158 }, { "C6",  160 },
  110.   { "B6",  162 }, { "A6S", 164 }, { "A6",  166 }, { "G7S", 168 },
  111.   { "G7",  170 }, { "F7S", 172 }, { "F7",  174 }, { "E7",  176 },
  112.   { "D7S", 178 }, { "D7",  180 }, { "C7S", 182 }, { "C7",  184 },
  113.   { "B7",  186 }, { "A7S", 188 },
  114.   { NULL, NULL }
  115. };
  116.  
  117. #define SND_FIELDS 9
  118.  
  119. struct Field SoundFields[SND_FIELDS] = {
  120.   { "Priority",  14, FID_Priority,  FDF_WORD|FDF_RANGE, 0, 1000, NULL, NULL },
  121.   { "Data",      16, FID_Data,      FDF_BYTEARRAY,      0, 0,    NULL, NULL },
  122.   { "Length",    20, FID_Length,    FDF_LONG,           0, 0,    NULL, NULL },
  123.   { "Octave",    24, FID_Octave,    FDF_WORD|FDF_LOOKUP, 0, 1000, NULL, NULL }, 
  124.   { "Volume",    26, FID_Volume,    FDF_WORD|FDF_RANGE, 0, 100,  NULL, NULL },
  125.   { "Attrib",    28, FID_Attrib,    FDF_LONG|FDF_FLAGS, (LONG)AttribFlags, 0, NULL, NULL },
  126.   { "Source",    32, FID_Source,    FDF_SOURCE,         0, 0,        NULL, NULL },
  127.   { "Frequency", 36, FID_Frequency, FDF_LONG,           0, 0,        NULL, NULL },
  128.   { "Pair",      40, FID_Sound,     FDF_OBJECT,         ID_SOUND, 0, NULL, NULL },
  129. };
  130.  
  131. /************************************************************************************
  132. ** Command:  Init()
  133. **
  134. ** Called when our module is being opened for the first time.
  135. */
  136.  
  137. LIBFUNC LONG CMDInit(mreg(__a0) LONG argModule,
  138.                      mreg(__a1) LONG argDPKBase,
  139.                      mreg(__a2) LONG argGVBase,
  140.                      mreg(__d0) LONG argDPKVersion,
  141.                      mreg(__d1) LONG argDPKRevision)
  142. {
  143.   APTR *Exec = (APTR *)4;
  144.  
  145.   DPKBase = (APTR)argDPKBase;
  146.   GVBase  = (struct GVBase *)argGVBase;
  147.   Public  = ((struct Module *)argModule)->Public;
  148.   SysBase = Exec[0];
  149.   FileMod = NULL;
  150.  
  151.   if ((argDPKVersion < DPKVersion) OR
  152.      ((argDPKVersion IS DPKVersion) AND (argDPKRevision < DPKRevision))) {
  153.      DPrintF("!Sound:","This module requires V%d.%d of the dpkernel.library.",DPKVersion,DPKRevision);
  154.   }
  155.   else {
  156.      if (FileMod = Get(ID_MODULE|GET_NOTRACK)) {
  157.         FileMod->Number = MOD_FILES;
  158.         if (Init(FileMod,NULL)) {
  159.            FILBase = FileMod->ModBase;
  160.  
  161.            if (SndObject = AddSysObjectTags(ID_SOUND, ID_SOUND, "Sound",
  162.                  TAGS, NULL,
  163.                  SOA_FileExtension, "iff;8svx;snd",
  164.                  SOA_FileDesc,      "IFF Sound Sample",
  165.                  SOA_Activate,      SND_Activate,
  166.                  SOA_CheckFile,     SND_CheckFile,
  167.                  SOA_Deactivate,    SND_Deactivate,
  168.                  SOA_CopyToUnv,     SND_CopyToUnv,
  169.                  SOA_CopyFromUnv,   SND_CopyFromUnv,
  170.                  SOA_Free,          SND_Free,
  171.                  SOA_Get,           SND_Get,
  172.                  SOA_Init,          SND_Init,
  173.                  SOA_Load,          SND_Load,
  174.                  SOA_FieldArray,    SoundFields,
  175.                  SOA_FieldTotal,    SND_FIELDS,
  176.                  SOA_FieldSize,     sizeof(struct Field),
  177.                  SOA_ClassVersion,  VER_SOUND,
  178.                  TAGEND)) {
  179.                  
  180.               return(ERR_OK);
  181.            }
  182.         }
  183.      }
  184.   }
  185.  
  186.   FreeModule();
  187.   return(ERR_FAILED);
  188. }
  189.  
  190. /************************************************************************************
  191. ** Command:  Open()
  192. **
  193. ** Called when our module is being opened for a second time...
  194. */
  195.  
  196. LIBFUNC LONG CMDOpen(mreg(__a0) struct Module *Module)
  197. {
  198.   if ((Module) AND (Public)) {
  199.      Module->FunctionList = JumpTableV1;
  200.      Public->OpenCount++;
  201.      return(ERR_OK);
  202.   }
  203.   else return(ERR_FAILED);
  204. }
  205.  
  206. /************************************************************************************
  207. ** Command:  Expunge()
  208. ** Synopsis: LONG Expunge(void);
  209. **
  210. ** Called on expunge - if no program has us opened then we can give permission to
  211. ** have us shut us down.
  212. **
  213. */
  214.  
  215. LIBFUNC LONG CMDExpunge(void)
  216. {
  217.   if (Public) {
  218.      if (Public->OpenCount IS NULL) {
  219.         FreeModule();
  220.         return(ERR_OK); /* Okay to expunge */
  221.      }
  222.   }
  223.   else DPrintF("!Sound:","I have no Public base reference.");
  224.  
  225.   return(ERR_FAILED); /* Do not expunge */
  226. }
  227.  
  228. /************************************************************************************
  229. ** Command:  Close()
  230. ** Synopsis: void Close(*Module [a0]);
  231. */
  232.  
  233. LIBFUNC void CMDClose(mreg(__a0) struct Module *Module)
  234. {
  235.   if (Public) Public->OpenCount--;
  236. }
  237.  
  238. /************************************************************************************
  239. ** Internal: FreeModule()
  240. **
  241. ** Frees any allocations made in the opening of our module.
  242. */
  243.  
  244. void FreeModule(void) {
  245.   if (SndObject) {
  246.      RemSysObject(SndObject);
  247.      SndObject = NULL;
  248.   }
  249.  
  250.   if (FileMod) {
  251.      Free(FileMod);
  252.      FileMod = NULL;
  253.   }
  254. }
  255.  
  256. /************************************************************************************
  257. ** Internal: FindHeader
  258. ** Synopsis: Chunk = FindHeader(FORM);
  259. */
  260.  
  261. APTR FindHeader(LONG *form, LONG ID)
  262. {
  263.    BYTE *endiff = (BYTE *)form;
  264.    BYTE *bytetmp;
  265.  
  266.    if ((form[0] IS CODE_FORM) AND (ID != NULL)) {
  267.       endiff += form[1] + 8;     /* Find the end */
  268.       form   += 3;               /* Skip FORM/Size/ILBM */
  269.  
  270.       while (form < (LONG *)endiff) {
  271.          if (form[0] IS ID) {
  272.             return(form+2);
  273.          }
  274.  
  275.          bytetmp = (BYTE *)form + form[1] + 8;
  276.          form    = (LONG *)bytetmp;
  277.  
  278.          /* Check for an uneven offset, if detected then
  279.          ** add an extra 1 to make it all even.
  280.          */
  281.  
  282.          if ((LONG)form & 0x00000001) {
  283.             form = (LONG *)((LONG)form + 1);
  284.          }
  285.       }
  286.       DPrintF("FindHeader:","Failed to find IFF chunk $%x.",ID);
  287.    }
  288.    else ErrCode(ERR_ARGS);
  289.  
  290.    return(NULL);
  291. }
  292.  
  293. #include "SND_CopyStructure.c"
  294. #include "SND_Init.c"
  295. #include "SND_Misc.c"
  296. #include "LIB_Memory.c"
  297.  
  298.